﻿using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using DailyPoetryX.Models;
using DailyPoetryX.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Xamarin.Forms.Extended;

namespace DailyPoetryX.ViewModels {
    /// <summary>
    /// 搜索结果页ViewModel。
    /// </summary>
    public class ResultPageViewModel : ViewModelBase {
        /******** 构造函数 ********/

        /// <summary>
        /// 内容导航服务。
        /// </summary>
        private IContentNavigationService _contentNavigationService;

        /// <summary>
        /// 搜索结果页ViewModel。
        /// </summary>
        /// <param name="poetryStorage">诗词存储。</param>
        /// <param name="contentNavigationService">内容导航服务。</param>
        public ResultPageViewModel(IPoetryStorage poetryStorage,
            IContentNavigationService contentNavigationService) {
            _contentNavigationService = contentNavigationService;

            PoetryCollection = new InfiniteScrollCollection<Poetry> {
                OnCanLoadMore = () => _canLoadMore,
                OnLoadMore = async () => {
                    Status = Loading;
                    var poetries = await poetryStorage.GetPoetriesAsync(Where,
                        PoetryCollection.Count, PageSize);
                    Status = "";

                    if (poetries.Count < PageSize) {
                        _canLoadMore = false;
                        Status = NoMoreResult;
                    }

                    if (PoetryCollection.Count == 0 && poetries.Count == 0) {
                        Status = NoResult;
                    }

                    return poetries;
                }
            };
        }

        /******** 绑定属性 ********/

        /// <summary>
        /// 加载状态。
        /// </summary>
        public string Status {
            get => _status;
            set => Set(nameof(Status), ref _status, value);
        }

        /// <summary>
        /// 加载状态。
        /// </summary>
        private string _status;

        /// <summary>
        /// 诗词集合。
        /// </summary>
        public InfiniteScrollCollection<Poetry> PoetryCollection { get; }

        /// <summary>
        /// 查询语句。
        /// </summary>
        public Expression<Func<Poetry, bool>> Where {
            get => _where;
            set {
                Set(nameof(Where), ref _where, value);
                _newQuery = true;
            }
        }

        /// <summary>
        /// 查询语句。
        /// </summary>
        private Expression<Func<Poetry, bool>> _where;

        /******** 绑定命令 ********/

        /// <summary>
        /// 页面显示命令。
        /// </summary>
        public RelayCommand PageAppearingCommand =>
            _pageAppearingCommand ?? (_pageAppearingCommand = new RelayCommand(
                async () => await PageAppearingCommandFunction()));

        /// <summary>
        /// 页面显示命令。
        /// </summary>
        private RelayCommand _pageAppearingCommand;

        internal async Task PageAppearingCommandFunction() {
            if (!_newQuery) return;
            _newQuery = false;

            PoetryCollection.Clear();
            _canLoadMore = true;
            await PoetryCollection.LoadMoreAsync();
        }

        /// <summary>
        /// 诗词点击命令。
        /// </summary>
        public RelayCommand<Poetry> PoetryTappedCommand =>
            _poetryTappedCommand ?? (_poetryTappedCommand =
                new RelayCommand<Poetry>(async poetry =>
                    await PoetryTappedCommandFunction(poetry)));

        /// <summary>
        /// 诗词点击命令。
        /// </summary>
        private RelayCommand<Poetry> _poetryTappedCommand;

        internal async Task PoetryTappedCommandFunction(Poetry poetry) =>
            await _contentNavigationService.NavigateToAsync(
                ContentNavigationServiceConstants.DetailPage, poetry);

        /******** 公开变量 ********/

        /// <summary>
        /// 一页显示的诗词数量。
        /// </summary>
        public const int PageSize = 20;

        /// <summary>
        /// 正在载入。
        /// </summary>
        public const string Loading = "正在载入";

        /// <summary>
        /// 没有满足条件的结果。
        /// </summary>
        public const string NoResult = "没有满足条件的结果";

        /// <summary>
        /// 没有更多结果。
        /// </summary>
        public const string NoMoreResult = "没有更多结果";

        /******** 私有变量 ********/

        /// <summary>
        /// 是否为新查询。
        /// </summary>
        private bool _newQuery;

        /// <summary>
        /// 能否加载更多诗词。
        /// </summary>
        private bool _canLoadMore;
    }
}